﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media;
using MaterialDesignThemes.Wpf;
using System.Net.NetworkInformation;
using System.Windows.Data;
using System.ComponentModel;
using Prism.Ioc;
using System.Runtime.CompilerServices;
using AntMovement.Core.Logic.Base;
using AntMovement.Core.IParameter;

namespace AntMovement.WPF.Resources.Controls
{
    [TemplatePart(Name = SingleControlPartName, Type = typeof(SingleControl))]
    public class SingleControl : ContentControl, INotifyPropertyChanged
    {
        public const string SingleControlPartName = "PART_SingleControl";
        private ISingleControl _entity;

        public ISingleControl Entity
        {
            get { return _entity; }
            set { SetProperty(ref _entity, value); }
        }

        private IContainerProvider _containerProvider;
        static SingleControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(SingleControl), new FrameworkPropertyMetadata(typeof(SingleControl)));
        }

        public SingleControl()
        {
            _containerProvider = ContainerLocator.Container;
            Binding bindingName = new Binding();
            bindingName.Source = this;
            bindingName.Path = new PropertyPath("Entity.Name");
            bindingName.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(this, SingleControl.TitleProperty, bindingName);

            Binding bindingSignal = new Binding();
            bindingSignal.Source = this;
            bindingSignal.Path = new PropertyPath("Entity.Signal");
            bindingSignal.Mode = BindingMode.OneWay;
            BindingOperations.SetBinding(this, SingleControl.SignalProperty, bindingSignal);

            Binding bindingIn_Text = new Binding();
            bindingIn_Text.Source = this;
            bindingIn_Text.Path = new PropertyPath("Entity.In_Text");
            bindingIn_Text.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(this, SingleControl.In_TextProperty, bindingIn_Text);

            Binding bindingOut_Text = new Binding();
            bindingOut_Text.Source = this;
            bindingOut_Text.Path = new PropertyPath("Entity.Out_Text");
            bindingOut_Text.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(this, SingleControl.Out_TextProperty, bindingOut_Text);

            Binding bindingOpen = new Binding();
            bindingOpen.Source = this;
            bindingOpen.Path = new PropertyPath("Entity.Manual_Open");
            bindingOpen.Mode = BindingMode.TwoWay;
            bindingOpen.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(this, SingleControl.OpenProperty, bindingOpen);

            Binding bindingClose = new Binding();
            bindingClose.Source = this;
            bindingClose.Path = new PropertyPath("Entity.Manual_Close");
            bindingClose.Mode = BindingMode.TwoWay;
            bindingClose.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            BindingOperations.SetBinding(this, SingleControl.CloseProperty, bindingClose);
        }


        #region 依赖属性
        public string OpenName
        {
            set => SetValue(OpenNameProperty, value);
            get => GetValue(OpenNameProperty) as string;
        }

        public static readonly DependencyProperty OpenNameProperty =
            DependencyProperty.Register(nameof(OpenName), typeof(string), typeof(SingleControl), new FrameworkPropertyMetadata("打开"));

        public string CloseName
        {
            set => SetValue(CloseNameProperty, value);
            get => GetValue(CloseNameProperty) as string;
        }

        public static readonly DependencyProperty CloseNameProperty =
            DependencyProperty.Register(nameof(CloseName), typeof(string), typeof(SingleControl), new FrameworkPropertyMetadata("打开"));
        public string Title
        {
            set => SetValue(TitleProperty, value);
            get => GetValue(TitleProperty) as string;
        }

        public static readonly DependencyProperty TitleProperty =
            DependencyProperty.Register(nameof(Title), typeof(string), typeof(SingleControl), new FrameworkPropertyMetadata("名字"));

        public string ControlType
        {
            set => SetValue(ControlTypeProperty, value);
            get => GetValue(ControlTypeProperty) as string;
        }

        public static readonly DependencyProperty ControlTypeProperty =
            DependencyProperty.Register(nameof(ControlType), typeof(string), typeof(SingleControl), new FrameworkPropertyMetadata("控制类型"));

        public static readonly DependencyProperty SignalProperty
            = DependencyProperty.Register(nameof(Signal), typeof(bool), typeof(SingleControl),
                new FrameworkPropertyMetadata(default(bool)));
        public bool Signal
        {
            get => (bool)GetValue(SignalProperty);
            private set => SetValue(SignalProperty, value);
        }

        public static DependencyProperty UpdateBindProperty = DependencyProperty.RegisterAttached(nameof(UpdateBind), typeof(bool), typeof(SingleControl), new PropertyMetadata(false, UpdateBindChanged));

        public bool UpdateBind
        {
            get => (bool)GetValue(UpdateBindProperty);
            set => SetValue(UpdateBindProperty, value);
        }

        private static void UpdateBindChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            SingleControl control = d as SingleControl;
            if (control == null)
            {
                return;
            }
            if (e.NewValue is Boolean bl && bl)
            {
                control.SetObject(control.Title, control.ControlType);
            }
        }

        public static readonly DependencyProperty OpenProperty
            = DependencyProperty.Register(nameof(Open), typeof(bool?), typeof(SingleControl),
                new FrameworkPropertyMetadata(default(bool?)));
        public bool? Open
        {
            get => (bool?)GetValue(OpenProperty);
            set => SetValue(OpenProperty, value);
        }

        public static readonly DependencyProperty CloseProperty
            = DependencyProperty.Register(nameof(Close), typeof(bool?), typeof(SingleControl),
                new FrameworkPropertyMetadata(default(bool?)));
        public bool? Close
        {
            get => (bool?)GetValue(CloseProperty);
            set => SetValue(CloseProperty, value);
        }

        public string In_Text
        {
            set => SetValue(In_TextProperty, value);
            get => GetValue(In_TextProperty) as string;
        }

        public static readonly DependencyProperty In_TextProperty =
            DependencyProperty.Register(nameof(In_Text), typeof(string), typeof(SingleControl), new FrameworkPropertyMetadata("X0000"));

        public string Out_Text
        {
            set => SetValue(Out_TextProperty, value);
            get => GetValue(Out_TextProperty) as string;
        }

        public static readonly DependencyProperty Out_TextProperty =
            DependencyProperty.Register(nameof(Out_Text), typeof(string), typeof(SingleControl), new FrameworkPropertyMetadata("Y0000"));
        #endregion
        public void SetObject(string title, string type)
        {
            Entity = _containerProvider.Resolve<IIOParameter>().GetSingleControl(title, type);
            switch (type)
            {
                case "大气":
                case "真空":
                    OpenName = "打开";
                    CloseName = "关闭";
                    break;
                case "电机":
                    OpenName = "启动";
                    CloseName = "停止";
                    break;
            }
        }
        #region 双向绑定通知实现
        bool SetProperty<T>(ref T member, T value, [CallerMemberName] string? propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(member, value))
            {
                return false;
            }

            member = value;
            OnPropertyChanged(propertyName);
            return true;
        }

        public event PropertyChangedEventHandler? PropertyChanged;
        void OnPropertyChanged([CallerMemberName] string? propertyName = null)
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        #endregion
    }
}
